function getRowFieldValue(row, query) {
  const key = Object.keys(query)[0]
  const keys = key.split('.')
  if (!row) return null
  let leaf = row
  for (let i = 0; i < keys.length; i++) {
    leaf = leaf[keys[i]]
  }
  return leaf
}

function findRows(rows, query) {
  if (!rows || !rows.length) return []
  const key = Object.keys(query)[0]
  const keys = key.split('.')
  const searchValue = query[key]
  const filteredRows = rows.filter(row => {
    const rowFieldValue = getRowFieldValue(row, query) || ''
    if(rowFieldValue || typeof rowFieldValue == 'string') return rowFieldValue.match(searchValue)
  })
  return filteredRows
}

function filter(rows, querys) {
  let resultRows = rows
  Object.keys(querys).forEach(key => {
    const query = {}
    query[key] = querys[key]
    resultRows = findRows(resultRows, query)
  })
  return resultRows
}

function getPathObj(obj, key) {
  const keys = key.split('.')
  let leaf = obj
  for (let i = 0; i < keys.length - 1; i++) {
    leaf = leaf[keys[i]]
  }
  return leaf
}

function highlight(resultRows, query) {
  resultRows.forEach(row => {
    Object.keys(query).forEach(key => {
      const obj = {}
      obj[key] = query[key]
      const searchValue = query[key]
      const sourceFieldObj = getPathObj(row._row, key)
      const targetFieldObj = getPathObj(row, key)
      const keys = key.split('.')
      const lastKey = keys[keys.length - 1]
      if (searchValue) {
        let replaceReg = new RegExp(searchValue, 'g')
        let replaceString = '<span style="background: #FEDF78">' + searchValue + '</span>'
        targetFieldObj[lastKey] = sourceFieldObj[lastKey].replace(replaceReg, replaceString)
      } else {
        targetFieldObj[lastKey] = sourceFieldObj[lastKey]
      }
    })
  })
}

export default class Searcher {
  rows = []
  query = {}
  resultRows = []

  constructor(rows, query) {
    this.rows = JSON.parse(JSON.stringify(rows))  // 拷贝一份列表副本
    this.resultRows = this.rows.map(row => {
      row._row = JSON.parse(JSON.stringify(row))  // 备份每列数据的副本
      return row
    })
    this.query = query
  }

  search() {
    Object.keys(this.query).forEach(key => {
      const query = {}
      query[key] = this.query[key]
      this.resultRows = findRows(this.resultRows, query)
      highlight(this.resultRows, this.query)
    })
    return this.resultRows
  }
}